package com.module.admin.ms.service.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;

import com.module.admin.ms.dao.MsConfigDao;
import com.module.admin.ms.pojo.MsConfig;
import com.module.admin.ms.service.MsConfigService;
import com.module.admin.prj.pojo.PrjInfo;
import com.module.admin.prj.service.PrjInfoService;
import com.ms.env.EnvUtil;
import com.system.auth.AuthUtil;
import com.system.comm.enums.Boolean;
import com.system.comm.model.Page;
import com.system.comm.utils.FrameHttpUtil;
import com.system.comm.utils.FrameJsonUtil;
import com.system.comm.utils.FrameStringUtil;
import com.system.handle.model.ResponseCode;
import com.system.handle.model.ResponseFrame;

/**
 * ms_config的Service
 * @author yuejing
 * @date 2017-04-21 16:02:31
 * @version V1.0.0
 */
@Component
public class MsConfigServiceImpl implements MsConfigService {

	private static final Logger LOGGER = LoggerFactory.getLogger(MsConfigServiceImpl.class);
	@Autowired
	private MsConfigDao msConfigDao;
	@Autowired
	private PrjInfoService prjInfoService;
	@Autowired
	private DiscoveryClient discoveryClient;

	@Override
	public ResponseFrame save(MsConfig msConfig) {
		ResponseFrame frame = new ResponseFrame();
		/*if (copyConfigId != null) {
			// 复制值
			MsConfig copyConfig = get(copyConfigId);
			if (copyConfig != null) {
				msConfig.setContent(copyConfig.getContent());
			}
		}*/
		MsConfig org = getUseByPrjId(msConfig.getPrjId());
		// 将原有的设为历史
		if (org != null) {
			msConfigDao.updateNotUse(org.getConfigId());
		}
		
		PrjInfo prj = prjInfoService.get(msConfig.getPrjId());
		if (FrameStringUtil.isEmpty(msConfig.getName())) {
			msConfig.setName(prj.getCode() + "." + msConfig.getType());
		}
		msConfig.setIsUse(1);
		msConfigDao.save(msConfig);
		if (Boolean.TRUE.getCode() == msConfig.getIsRefresh()) {
			refreshCfg(msConfig.getConfigId());
		}
		frame.setCode(ResponseCode.SUCC.getCode());
		return frame;
	}

	@Override
	public MsConfig get(Integer configId) {
		return msConfigDao.get(configId);
	}

	@Override
	public ResponseFrame pageQuery(MsConfig msConfig) {
		msConfig.setDefPageSize();
		ResponseFrame frame = new ResponseFrame();
		int total = msConfigDao.findMsConfigCount(msConfig);
		List<MsConfig> data = null;
		if(total > 0) {
			data = msConfigDao.findMsConfig(msConfig);
			for (MsConfig mc : data) {
				mc.setIsUseName(Boolean.getText(mc.getIsUse()));
				mc.setPrjName(prjInfoService.getName(mc.getPrjId()));
			}
		}
		Page<MsConfig> page = new Page<MsConfig>(msConfig.getPage(), msConfig.getSize(), total, data);
		frame.setBody(page);
		frame.setCode(ResponseCode.SUCC.getCode());
		return frame;
	}

	@Override
	public ResponseFrame delete(Integer configId) {
		ResponseFrame frame = new ResponseFrame();
		msConfigDao.delete(configId);
		frame.setCode(ResponseCode.SUCC.getCode());
		return frame;
	}

	@Override
	public List<MsConfig> findUse() {
		return msConfigDao.findUse();
	}

	@Override
	public List<MsConfig> findAll() {
		return msConfigDao.findAll();
	}

	@Override
	public ResponseFrame refreshCfg(Integer configId) {
		ResponseFrame frame = new ResponseFrame();
		MsConfig config = get(configId);
		if(Boolean.FALSE.getCode() == config.getIsUse().intValue()) {
			frame.setSucc();
			return frame;
		}
		String serviceId = null;
		int index = config.getName().indexOf(".");
		if(index != -1) {
			serviceId = config.getName().substring(0, index);
		} else {
			serviceId = config.getName();
		}
		frame = refresh(serviceId);
		/*if(ResponseCode.SUCC.getCode() != frame.getCode().intValue()) {
			LOGGER.error("刷新服务配置失败!");
		}*/
		return frame;
	}

	public ResponseFrame refresh(String serviceId) {
		ResponseFrame frame = new ResponseFrame();
		try {
			List<ServiceInstance> list = discoveryClient.getInstances(EnvUtil.serviceIdConfig());
			for (ServiceInstance instance : list) {
				String baseUrl = instance.getUri().toString();
				Map<String, Object> params = new HashMap<String, Object>();
				String result = FrameHttpUtil.post(baseUrl + "/config/update", params);
				LOGGER.info("刷新配置中心[{}]成功，响应结果: {}", baseUrl, result);
			}
			list = discoveryClient.getInstances(serviceId);
			try {
				Thread.sleep(1500);
			} catch (InterruptedException e) {
			}
			for (ServiceInstance instance : list) {
				String baseUrl = instance.getUri().toString();
				Map<String, Object> params = new HashMap<String, Object>();
				String time = String.valueOf(System.currentTimeMillis());
				params.put("clientId", com.ms.MsConfig.getClientId());
				params.put("time", time);
				params.put("sign", AuthUtil.auth(com.ms.MsConfig.getClientId(), time, com.ms.MsConfig.getSercret()));
				// springBoot 2.0的调用刷新方法
				String result = FrameHttpUtil.post(baseUrl + "/actuator/refresh", FrameJsonUtil.toString(params));
				if(FrameStringUtil.isNotEmpty(result) && "[]".equals(result)) {
					String message = baseUrl + "无刷新内容, 响应结果:" + result;
					LOGGER.error(message);
					frame.setCode(-200);
					frame.setMessage("配置信息保存成功! - " + message);
					return frame;
				} else {
					String message = baseUrl + "刷新微服务配置文件, 响应结果:" + result;
					LOGGER.info(message);
				}
			}

			frame.setSucc();
			return frame;
		} catch (IOException e) {
			return new ResponseFrame(ResponseCode.SERVER_ERROR);
		}
	}

	@Override
	public void relationPrjId(Integer prjId) {
		PrjInfo prjInfo = prjInfoService.get(prjId);
		if(prjInfo != null) {
			msConfigDao.updatePrjIdByName(prjInfo.getName() + ".properties", prjInfo.getPrjId());
			prjInfo = prjInfoService.get(prjId);
			if(prjInfo != null) {
				msConfigDao.updatePrjIdByName(prjInfo.getName() + ".yml", prjInfo.getPrjId());
			}
		}
	}

	/*@Override
	public void updateContent(Integer configId, String content, Integer isRefresh) {
		msConfigDao.updateContent(configId, content);
		if (Boolean.TRUE.getCode() == isRefresh) {
			refreshCfg(configId);
		}
	}*/

	@Override
	public MsConfig getUseByPrjId(Integer prjId) {
		MsConfig config = msConfigDao.getUseByPrjId(prjId);
		return config;
	}
}
